#include <cstring>
#include <cassert>

#include "array.h"

// constructor
array::array(size_t size) : memory(new int[size]), size(size), capacity(size) {
	assert(memory != NULL);
}

// copy constructor
array::array(const array & obj) : memory(new int[obj.size]), size(obj.size), capacity(obj.size) {
	assert(memory != NULL);
	std::copy(obj.memory, obj.memory+obj.size, memory);
}

// desctructor
array::~array() {
	delete[] memory;
}

void array::swap(array & obj) {
	std::swap(obj.capacity, capacity);
	std::swap(obj.size, size);
	std::swap(obj.memory, memory);
}

array & array::operator=(array obj) {
	swap(obj);
	return *this;
}

int & array::operator[](size_t pos) {
	assert(pos < size);
	return memory[pos];
}

const int & array::operator[](size_t pos) const {
	assert(pos < size);
	return memory[pos];
}

void array::increase_size() {
	int * old_memory = memory;
	capacity *= 2;
	memory = new int[capacity];
	assert(memory != NULL);
	std::copy(old_memory, old_memory + size, memory);
	delete[] old_memory;
}

void array::push_back(int value) {
	if (capacity == size)
		increase_size();
	memory[size++] = value;
}

void array::set(size_t pos, int value) {
	assert(pos < size);
	memory[pos] = value;
}

int array::get(size_t pos) const {
	assert(pos < size);
	return memory[pos];
}

size_t array::get_size() const {
	return size;
}

void array::print(std::ostream & out) const {
	out << "[";
	for (int i = 0; i < size-1; i++)
		out << memory[i] << ",";
	if (size != 0)
		out << memory[size-1];
	out << "]";
}

std::ostream & operator<<(std::ostream & out, const array & obj) {
	obj.print(out);
	return out;
}
